/*
 * Copyright (c) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "camera_manager.h"

// #define LOG_TAG "DEMO:"
// #define LOG_DOMAIN 0x3200
// #define IMAGE_TYPE_JPEG MediaLibrary_ImageFileType::MEDIA_LIBRARY_IMAGE_JPEG
//
// MediaLibrary_ErrorCode result = MEDIA_LIBRARY_OK;
// OH_MediaAsset *g_mediaAsset = nullptr;
// OH_MediaAssetManager *g_mediaAssetManager = nullptr;
// OH_MediaAssetChangeRequest *g_changeRequest = nullptr;
// OH_ImageSourceNative *g_imageSourceNative = nullptr;
// OH_PixelmapNative *g_pixelmapNative = nullptr;
// MediaLibrary_RequestOptions g_requestOptions;
// MediaLibrary_RequestId g_requestId;
// MediaLibrary_DeliveryMode g_deliveryMode = MEDIA_LIBRARY_HIGH_QUALITY_MODE;
// char *g_mediaQualityCb = nullptr;
// static void (*g_requestImageQualityCallback)(char *) = nullptr;
// static void (*g_requestImageBufferCallback)(uint8_t *, size_t) = nullptr;
// float g_angle = 180.0f;
constexpr int DEFAULT_WIDTH = 1920;
constexpr int DEFAULT_HEIGHT = 1080;
// constexpr int REQUEST_OPTION_TWO = 2;
// constexpr int DEFAULT_QUALITY = 100;

namespace OHOS_CAMERA_SAMPLE {
NDKCamera *NDKCamera::ndkCamera_ = nullptr;
std::mutex NDKCamera::mtx_;
const std::unordered_map<uint32_t, Camera_SceneMode> g_int32ToCameraSceneMode = {
    {1, Camera_SceneMode::NORMAL_PHOTO}, {2, Camera_SceneMode::NORMAL_VIDEO}, {12, Camera_SceneMode::SECURE_PHOTO}};

NDKCamera::NDKCamera(uint32_t focusMode, uint32_t cameraDeviceIndex, uint32_t sceneMode, char *previewId, char *photoId,
                     char *videoId)
    : focusMode_(focusMode), cameraDeviceIndex_(cameraDeviceIndex), previewSurfaceId_(previewId),
      photoSurfaceId_(photoId), videoSurfaceId_(videoId), cameras_(nullptr), profile_(nullptr),
      cameraOutputCapability_(nullptr), captureSession_(nullptr), cameraInput_(nullptr), previewOutput_(nullptr),
      photoOutput_(nullptr), videoOutput_(nullptr), isCameraMuted_(nullptr), metaDataObjectType_(nullptr),
      metadataOutput_(nullptr), isExposureModeSupported_(false), isFocusModeSupported_(false), isSuccess_(false),
      sceneMode_(NORMAL_PHOTO), exposureMode_(EXPOSURE_MODE_LOCKED), ret_(CAMERA_OK), size_(0), minExposureBias_(0),
      maxExposureBias_(0), step_(0) {
    // release camera
    ReleaseCamera();

    // create camera manager
    Camera_ErrorCode ret = OH_Camera_GetCameraManager(&cameraManager_);
    if (cameraManager_ == nullptr || ret != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "Get CameraManager failed.");
    }

    // register camera manager callback
    //     CameraManagerRegisterCallback();

    // create capture session
    ret = OH_CameraManager_CreateCaptureSession(cameraManager_, &captureSession_);
    if (captureSession_ == nullptr || ret != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "Create captureSession failed.");
    }

    // look up sceneMode
    auto itr1 = g_int32ToCameraSceneMode.find(sceneMode);
    if (itr1 != g_int32ToCameraSceneMode.end()) {
        sceneMode_ = itr1->second;
    }

    // set session mode
    ret = OH_CaptureSession_SetSessionMode(captureSession_, NORMAL_VIDEO);
    //     DRAWING_LOGD("OH_CaptureSession_SetSessionMode sceneMode_: %{public}d!", sceneMode_);
    //     DRAWING_LOGD("OH_CaptureSession_SetSessionMode return with ret code: %{public}d!", ret);

    // register capture session callback
    //     CaptureSessionRegisterCallback();

    // get capture session profile
    GetSupportedCameras();
    GetSupportedOutputCapability();

    // create preview output
    CreatePreviewOutput();

    // create camera input and register camera input callback
    CreateCameraInput();
    CameraInputOpen();

    // config and start session
    SessionFlowFn();
}

NDKCamera::~NDKCamera() {
    OH_LOG_ERROR(LOG_APP, "~NDKCamera");
    Camera_ErrorCode ret = CAMERA_OK;

    if (cameraManager_) {
        OH_LOG_ERROR(LOG_APP, "Release OH_CameraManager_DeleteSupportedCameraOutputCapability. enter");
        ret = OH_CameraManager_DeleteSupportedCameraOutputCapability(cameraManager_, cameraOutputCapability_);
        if (ret != CAMERA_OK) {
            OH_LOG_ERROR(LOG_APP, "Delete CameraOutputCapability failed.");
        } else {
            OH_LOG_ERROR(LOG_APP, "Release OH_CameraManager_DeleteSupportedCameraOutputCapability. ok");
        }

        OH_LOG_ERROR(LOG_APP, "Release OH_CameraManager_DeleteSupportedCameras. enter");
        ret = OH_CameraManager_DeleteSupportedCameras(cameraManager_, cameras_, size_);
        if (ret != CAMERA_OK) {
            OH_LOG_ERROR(LOG_APP, "Delete Cameras failed.");
        } else {
            OH_LOG_ERROR(LOG_APP, "Release OH_CameraManager_DeleteSupportedCameras. ok");
        }

        ret = OH_Camera_DeleteCameraManager(cameraManager_);
        if (ret != CAMERA_OK) {
            OH_LOG_ERROR(LOG_APP, "Delete CameraManager failed.");
        } else {
            OH_LOG_ERROR(LOG_APP, "Release OH_Camera_DeleteCameraMananger. ok");
        }
        cameraManager_ = nullptr;
    }
    OH_LOG_ERROR(LOG_APP, "~NDKCamera exit");
}

Camera_ErrorCode NDKCamera::ReleaseCamera(void) {
    OH_LOG_ERROR(LOG_APP, " enter ReleaseCamera");
    if (previewOutput_ && captureSession_) {
        PreviewOutputStop();
        OH_CaptureSession_RemovePreviewOutput(captureSession_, previewOutput_);
        PreviewOutputRelease();
    }
    if (photoOutput_) {
        PhotoOutputRelease();
    }

    if (videoOutput_) {
        VideoOutputRelease();
    }
    if (captureSession_) {
        SessionRealese();
    }
    if (cameraInput_) {
        CameraInputClose();
    }
    OH_LOG_ERROR(LOG_APP, " exit ReleaseCamera");
    return ret_;
}

Camera_ErrorCode NDKCamera::ReleaseSession(void) {
    OH_LOG_ERROR(LOG_APP, " enter ReleaseSession");
    PreviewOutputStop();
    PhotoOutputRelease();
    VideoOutputRelease();
    SessionRealese();
    OH_LOG_ERROR(LOG_APP, " exit ReleaseSession");
    return ret_;
}

Camera_ErrorCode NDKCamera::SessionRealese(void) {
    OH_LOG_ERROR(LOG_APP, " enter SessionRealese");
    Camera_ErrorCode ret = OH_CaptureSession_Release(captureSession_);
    captureSession_ = nullptr;
    OH_LOG_ERROR(LOG_APP, " exit SessionRealese");
    return ret;
}
// todo


Camera_ErrorCode NDKCamera::HasFlashFn(uint32_t mode) {
    Camera_FlashMode flashMode = static_cast<Camera_FlashMode>(mode);
    bool hasFlash = false;
    Camera_ErrorCode ret = OH_CaptureSession_HasFlash(captureSession_, &hasFlash);
    if (captureSession_ == nullptr || ret == CAMERA_OK) {
        OH_LOG_INFO(LOG_APP, "OH_CaptureSession_HasFlash success.");
    } else {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_HasFlash failed. %d ", ret);
    }
    if (hasFlash) {
        OH_LOG_INFO(LOG_APP, "hasFlash success.");
    } else {
        OH_LOG_ERROR(LOG_APP, "hasFlash hasFlash  failed. %d ", hasFlash);
    }
    bool isSupported=false;
    ret =OH_CaptureSession_IsFlashModeSupported(captureSession_, flashMode, &isSupported);
    
    if ( ret == CAMERA_OK) {
        OH_LOG_INFO(LOG_APP, "OH_CaptureSession_IsFlashModeSupported success.");
    } else {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_IsFlashModeSupported failed. %d ", ret);
    }
    
    if (isSupported) {
        OH_LOG_INFO(LOG_APP, "isSupported success.");
    } else {
        OH_LOG_ERROR(LOG_APP, "isSupported  failed. %d ", hasFlash);
    }
    
    ret=OH_CaptureSession_SetFlashMode(captureSession_, flashMode);
    
    if ( ret == CAMERA_OK) {
        OH_LOG_INFO(LOG_APP, "OH_CaptureSession_SetFlashMode success.");
    } else {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_SetFlashMode failed. %d ", ret);
    }
    ret=OH_CaptureSession_GetFlashMode(captureSession_, &flashMode);
    if ( ret == CAMERA_OK) {
        OH_LOG_INFO(LOG_APP, "OH_CaptureSession_GetFlashMode success.");
    } else {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_GetFlashMode failed. %d ", ret);
    }
    
    return ret;
}


Camera_ErrorCode NDKCamera::IsVideoStabilizationModeSupportedFn(uint32_t mode) {
    Camera_VideoStabilizationMode videoMode=static_cast<Camera_VideoStabilizationMode>(mode);
    bool isSupported=false;
    
    Camera_ErrorCode ret = OH_CaptureSession_IsVideoStabilizationModeSupported(captureSession_,videoMode,&isSupported);
    if (ret == CAMERA_OK) {
        OH_LOG_INFO(LOG_APP, "OH_CaptureSession_IsVideoStabilizationModeSupported success.");
    } else {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_IsVideoStabilizationModeSupported failed. %d ", ret);
    }
    if (isSupported) {
        OH_LOG_INFO(LOG_APP, "isSupported success.");
    } else {
        OH_LOG_ERROR(LOG_APP, "isSupported  failed. %d ", isSupported);
    }
    
     ret = OH_CaptureSession_SetVideoStabilizationMode(captureSession_,videoMode);
    if (ret == CAMERA_OK) {
        OH_LOG_INFO(LOG_APP, "OH_CaptureSession_SetVideoStabilizationMode success.");
    } else {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_SetVideoStabilizationMode videoMode failed. %d ", videoMode);
    }
     ret = OH_CaptureSession_GetVideoStabilizationMode(captureSession_,&videoMode);
    if (ret == CAMERA_OK) {
        OH_LOG_INFO(LOG_APP, "OH_CaptureSession_GetVideoStabilizationMode success.");
    } else {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_GetVideoStabilizationMode videoMode failed. %d ", videoMode);
    }
    return ret;
}

Camera_ErrorCode NDKCamera::setZoomRatioFn(uint32_t zoomRatio) {
    float zoom=float (zoomRatio);
    float minZoom;
    float maxZoom;
    
    Camera_ErrorCode ret = OH_CaptureSession_GetZoomRatioRange(captureSession_,&minZoom,&maxZoom);
    if (captureSession_==nullptr||ret == CAMERA_OK) {
        OH_LOG_INFO(LOG_APP, "OH_CaptureSession_GetZoomRatioRange success.");
    } else {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_GetZoomRatioRange failed. %d ", ret);
    }
    ret = OH_CaptureSession_SetZoomRatio(captureSession_,zoom);
    if (ret == CAMERA_OK) {
        OH_LOG_INFO(LOG_APP, "OH_CaptureSession_SetZoomRatio success.");
    } else {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_SetZoomRatio failed. %d ", ret);
    }
    
    ret = OH_CaptureSession_GetZoomRatio(captureSession_,&zoom);
    if (ret == CAMERA_OK) {
        OH_LOG_INFO(LOG_APP, "OH_CaptureSession_GetZoomRatio success.");
    } else {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_GetZoomRatio failed. %d ", ret);
    }
    return ret;
}

Camera_ErrorCode NDKCamera::SessionBegin(void) {
    Camera_ErrorCode ret = OH_CaptureSession_BeginConfig(captureSession_);
    if (ret == CAMERA_OK) {
        OH_LOG_INFO(LOG_APP, "OH_CaptureSession_BeginConfig success.");
    } else {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_BeginConfig failed. %d ", ret);
    }
    return ret;
}

Camera_ErrorCode NDKCamera::SessionCommitConfig(void) {
    Camera_ErrorCode ret = OH_CaptureSession_CommitConfig(captureSession_);
    if (ret == CAMERA_OK) {
        OH_LOG_INFO(LOG_APP, "OH_CaptureSession_CommitConfig success.");
    } else {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_CommitConfig failed. %d ", ret);
    }
    return ret;
}

Camera_ErrorCode NDKCamera::SessionStart(void) {
    bool isSupport = false;
    OH_CaptureSession_IsVideoStabilizationModeSupported(
        captureSession_, Camera_VideoStabilizationMode::STABILIZATION_MODE_AUTO, &isSupport);
    if (isSupport) {
        OH_CaptureSession_SetVideoStabilizationMode(captureSession_,
                                                    Camera_VideoStabilizationMode::STABILIZATION_MODE_AUTO);
    }
    // Start focusing
    OH_LOG_INFO(LOG_APP, "IsFocusMode start");
    OH_CaptureSession_SetFocusMode(captureSession_, Camera_FocusMode::FOCUS_MODE_AUTO);
    OH_LOG_INFO(LOG_APP, "IsFocusMode success");
    Camera_ErrorCode ret = OH_CaptureSession_Start(captureSession_);
    if (ret == CAMERA_OK) {
        OH_LOG_INFO(LOG_APP, "OH_CaptureSession_Start success.");
    } else {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_Start failed. %d ", ret);
    }
    return ret;
}

Camera_ErrorCode NDKCamera::SessionStop(void) {
    Camera_ErrorCode ret = OH_CaptureSession_Stop(captureSession_);
    if (ret == CAMERA_OK) {
        OH_LOG_INFO(LOG_APP, "OH_CaptureSession_Stop success.");
    } else {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_Stop failed. %d ", ret);
    }
    return ret;
}

Camera_ErrorCode NDKCamera::SessionFlowFn(void) {
    OH_LOG_INFO(LOG_APP, "Start SessionFlowFn IN.");
    // start configuring session
    OH_LOG_INFO(LOG_APP, "session beginConfig.");
    Camera_ErrorCode ret = OH_CaptureSession_BeginConfig(captureSession_);
    // add cameraInput to the session
    OH_LOG_INFO(LOG_APP, "session add Input.");
    ret = OH_CaptureSession_AddInput(captureSession_, cameraInput_);
    // add previewOutput to the session
    OH_LOG_INFO(LOG_APP, "session add Preview Output.");
    ret = OH_CaptureSession_AddPreviewOutput(captureSession_, previewOutput_);
    // create photo output and register photo output callback
    //     CreatePhotoOutputWithoutSurfaceId();
    // add photoOutput to the Session
    //     AddPhotoOutput();

    if (sceneMode_ == Camera_SceneMode::NORMAL_VIDEO) {
        CreateVideoOutput(videoSurfaceId_);

        AddVideoOutput();
    }
    // Submit configuration information
    OH_LOG_INFO(LOG_APP, "session commitConfig");
    ret = OH_CaptureSession_CommitConfig(captureSession_);
    // Start Session Work
    OH_LOG_INFO(LOG_APP, "session start");
    SessionStart();
    OH_LOG_INFO(LOG_APP, "session success");
    OH_VideoOutput_Start(videoOutput_);

    return ret;
}

Camera_ErrorCode NDKCamera::CreateCameraInput(void) {
    OH_LOG_ERROR(LOG_APP, "enter CreateCameraInput.");
    ret_ = OH_CameraManager_CreateCameraInput(cameraManager_, &cameras_[cameraDeviceIndex_], &cameraInput_);
    if (cameraInput_ == nullptr || ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "CreateCameraInput failed.");
        return CAMERA_INVALID_ARGUMENT;
    }
    OH_LOG_ERROR(LOG_APP, "exit CreateCameraInput.");
    // register camera input callback
    CameraInputRegisterCallback();
    return ret_;
}

Camera_ErrorCode NDKCamera::CameraInputOpen(void) {
    OH_LOG_ERROR(LOG_APP, "enter CameraInputOpen.");
    ret_ = OH_CameraInput_Open(cameraInput_);
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "CameraInput_Open failed.");
        return CAMERA_INVALID_ARGUMENT;
    }
    OH_LOG_ERROR(LOG_APP, "exit CameraInputOpen.");
    return ret_;
}

Camera_ErrorCode NDKCamera::CameraInputClose(void) {
    OH_LOG_ERROR(LOG_APP, "enter CameraInput_Close.");
    ret_ = OH_CameraInput_Close(cameraInput_);
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "CameraInput_Close failed.");
        return CAMERA_INVALID_ARGUMENT;
    }
    OH_LOG_ERROR(LOG_APP, "exit CameraInput_Close.");
    return ret_;
}

Camera_ErrorCode NDKCamera::CameraInputRelease(void) {
    ret_ = OH_CameraInput_Release(cameraInput_);
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "CameraInputRelease failed.");
        return CAMERA_INVALID_ARGUMENT;
    }
    OH_LOG_ERROR(LOG_APP, "exit CameraInputRelease.");
    return ret_;
}

Camera_ErrorCode NDKCamera::GetSupportedCameras(void) {
    ret_ = OH_CameraManager_GetSupportedCameras(cameraManager_, &cameras_, &size_);
    //     if (ret_ != CAMERA_OK || &size_ == nullptr || cameras_ == nullptr) {
    if (ret_ != CAMERA_OK || cameras_ == nullptr || &size_ == nullptr) {
        OH_LOG_ERROR(LOG_APP, "GetSupportedCaneras failed.");
        return CAMERA_INVALID_ARGUMENT;
    }
    OH_LOG_ERROR(LOG_APP, "exit GetSupportedCaneras.");
    return ret_;
}
Camera_ErrorCode NDKCamera::GetSupportedOutputCapability(void) {
    ret_ = OH_CameraManager_GetSupportedCameraOutputCapability(cameraManager_, &cameras_[cameraDeviceIndex_],
                                                               &cameraOutputCapability_);
    if (ret_ != CAMERA_OK || cameraOutputCapability_ == nullptr) {
        OH_LOG_ERROR(LOG_APP, "GetSupportedOutputCapability failed.");
        return CAMERA_INVALID_ARGUMENT;
    }
    OH_LOG_ERROR(LOG_APP, "exit GetSupportedOutputCapability.");
    return ret_;
}

Camera_ErrorCode NDKCamera::CreatePreviewOutput(void) {
    profile_ = cameraOutputCapability_->previewProfiles[0];
    if (profile_ == nullptr) {
        OH_LOG_ERROR(LOG_APP, "CreatePreviewOutput failed.");
        return CAMERA_INVALID_ARGUMENT;
    }
    OH_LOG_ERROR(LOG_APP, "exit CreatePreviewOutput.");
    profile_->size.width = DEFAULT_WIDTH;
    profile_->size.height = DEFAULT_HEIGHT;
    ret_ = OH_CameraManager_CreatePreviewOutput(cameraManager_, profile_, previewSurfaceId_, &previewOutput_);

    if (previewSurfaceId_ == nullptr || previewOutput_ == nullptr || ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "OH_CameraManager_CreatePreviewOutput failed.");
        return CAMERA_INVALID_ARGUMENT;
    }
    PreviewOutputRegisterCallback();
    return ret_;
}

// todo

// Camera_ErrorCode NDKCamera::GetSupportedCameras(void) {
//     ret_ = OH_CameraManager_GetSupportedCameras(cameraManager_, &cameras_, &size_);
//     if (cameras_ == nullptr || &size_ == nullptr || ret_ != CAMERA_OK) {
//         OH_LOG_ERROR(LOG_APP, "Get supported cameras failed.");
//         return CAMERA_INVALID_ARGUMENT;
//     }
//     return ret_;
// }
//
// Camera_ErrorCode NDKCamera::GetSupportedOutputCapability(void) {
//     ret_ = OH_CameraManager_GetSupportedCameraOutputCapability(cameraManager_, &cameras_[cameraDeviceIndex_],
//                                                                &cameraOutputCapability_);
//     if (cameraOutputCapability_ == nullptr || ret_ != CAMERA_OK) {
//         OH_LOG_ERROR(LOG_APP, "GetSupportedCameraOutputCapability failed.");
//         return CAMERA_INVALID_ARGUMENT;
//     }
//     return ret_;
// }
//
// Camera_ErrorCode NDKCamera::CreatePreviewOutput(void) {
//     DRAWING_LOGD("NDKCamera::CreatePreviewOutput start!");
//     profile_ = cameraOutputCapability_->previewProfiles[0];
//     if (profile_ == nullptr) {
//         OH_LOG_ERROR(LOG_APP, "Get previewProfiles failed.");
//         return CAMERA_INVALID_ARGUMENT;
//     }
//     profile_->size.width = DEFAULT_WIDTH;
//     profile_->size.height = DEFAULT_HEIGHT;
//     ret_ = OH_CameraManager_CreatePreviewOutput(cameraManager_, profile_, previewSurfaceId_, &previewOutput_);
//     if (previewSurfaceId_ == nullptr || previewOutput_ == nullptr || ret_ != CAMERA_OK) {
//         OH_LOG_ERROR(LOG_APP, "CreatePreviewOutput failed.");
//         return CAMERA_INVALID_ARGUMENT;
//     }
//     // register preview output callback
//     PreviewOutputRegisterCallback();
//     return ret_;
// }

Camera_ErrorCode NDKCamera::CreatePhotoOutput(char *photoSurfaceId) {
    DRAWING_LOGD("NDKCamera::CreatePhotoOutput start!");
    profile_ = cameraOutputCapability_->photoProfiles[0];
    if (profile_ == nullptr) {
        OH_LOG_ERROR(LOG_APP, "Get photoProfiles failed.");
        return CAMERA_INVALID_ARGUMENT;
    }
    profile_->size.width = DEFAULT_WIDTH;
    profile_->size.height = DEFAULT_HEIGHT;
    ret_ = OH_CameraManager_CreatePhotoOutput(cameraManager_, profile_, photoSurfaceId, &photoOutput_);
    if (photoSurfaceId == nullptr || photoOutput_ == nullptr || ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "CreatePhotoOutput failed.");
        return CAMERA_INVALID_ARGUMENT;
    }
    // register photo output callback
    PhotoOutputRegisterCallback();
    return ret_;
}

Camera_ErrorCode NDKCamera::CreateVideoOutput(char *videoId) {
    DRAWING_LOGD("NDKCamera::CreatePhotoOutput start!");
    videoProfile_ = cameraOutputCapability_->videoProfiles[0];
    if (videoProfile_ == nullptr) {
        OH_LOG_ERROR(LOG_APP, "Get photoProfiles failed.");
        return CAMERA_INVALID_ARGUMENT;
    }
    videoProfile_->size.width = DEFAULT_WIDTH;
    videoProfile_->size.height = DEFAULT_HEIGHT;
    ret_ = OH_CameraManager_CreateVideoOutput(cameraManager_, videoProfile_, videoId, &videoOutput_);
    if (videoId == nullptr || videoOutput_ == nullptr || ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "CreatePhotoOutput failed.");
        return CAMERA_INVALID_ARGUMENT;
    }
    // register photo output callback
    VideoOutputRegisterCallback();
    return ret_;
}
Camera_ErrorCode NDKCamera::AddVideoOutput(void) {
    Camera_ErrorCode ret = OH_CaptureSession_AddVideoOutput(captureSession_, videoOutput_);
    if (ret == CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_AddPhotoOutput success.");
    } else {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_AddPhotoOutput failed. %d ", ret);
    }
    return ret;
}

Camera_ErrorCode NDKCamera::AddPhotoOutput() {
    Camera_ErrorCode ret = OH_CaptureSession_AddPhotoOutput(captureSession_, photoOutput_);
    if (ret == CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_AddPhotoOutput success.");
    } else {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_AddPhotoOutput failed. %d ", ret);
    }
    return ret;
}

Camera_ErrorCode NDKCamera::CreateMetadataOutput(void) {
    DRAWING_LOGD("NDKCamera::CreateMetadataOutput start!");
    metaDataObjectType_ = cameraOutputCapability_->supportedMetadataObjectTypes[0];
    if (metaDataObjectType_ == nullptr) {
        OH_LOG_ERROR(LOG_APP, "Get CreateMetadataOutput failed.");
        return CAMERA_INVALID_ARGUMENT;
    }
    Camera_ErrorCode ret = OH_CameraManager_CreateMetadataOutput(cameraManager_, metaDataObjectType_, &metadataOutput_);
    if (metadataOutput_ == nullptr || ret == CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "OH_CameraManager_CreateMetadataOutput success.");
    } else {
        OH_LOG_ERROR(LOG_APP, "OH_CameraManager_CreateMetadataOutput failed. %d ", ret);
    }
    MetadataOutputRegisterCallback();
    return ret;
}

Camera_ErrorCode NDKCamera::IsCameraMuted(void) {
    OH_LOG_ERROR(LOG_APP, "enter IsCameraMuted.");
    ret_ = OH_CameraManager_IsCameraMuted(cameraManager_, isCameraMuted_);
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "IsCameraMuted failed.");
        return CAMERA_INVALID_ARGUMENT;
    }
    return ret_;
}

Camera_ErrorCode NDKCamera::PreviewOutputStop(void) {
    OH_LOG_ERROR(LOG_APP, "enter PreviewOutputStop.");
    ret_ = OH_PreviewOutput_Stop(previewOutput_);
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "PreviewOutputStop failed.");
        return CAMERA_INVALID_ARGUMENT;
    }
    return ret_;
}

Camera_ErrorCode NDKCamera::PreviewOutputRelease(void) {
    OH_LOG_ERROR(LOG_APP, "enter PreviewOutputRelease.");
    if (previewOutput_ != nullptr) {
        ret_ = OH_PreviewOutput_Release(previewOutput_);
        if (ret_ != CAMERA_OK) {
            OH_LOG_ERROR(LOG_APP, "PreviewOutputRelease failed.");
            return CAMERA_INVALID_ARGUMENT;
        }
        previewOutput_ = nullptr;
    }
    return CAMERA_OK;
}

Camera_ErrorCode NDKCamera::PhotoOutputRelease(void) {
    OH_LOG_ERROR(LOG_APP, "enter PhotoOutputRelease.");
    ret_ = OH_PhotoOutput_Release(photoOutput_);
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "PhotoOutputRelease failed.");
        return CAMERA_INVALID_ARGUMENT;
    }
    photoOutput_ = nullptr;
    return ret_;
}

Camera_ErrorCode NDKCamera::VideoOutputStart(void) {
    OH_LOG_ERROR(LOG_APP, "enter VideoOutputStart.");
    Camera_ErrorCode ret = OH_VideoOutput_Start(videoOutput_);
    if (ret != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "VideoOutputStart failed.");
    }
    return ret;
}

Camera_ErrorCode NDKCamera::IsExposureModeSupportedFn(uint32_t mode) {
    OH_LOG_ERROR(LOG_APP, "enter IsExposureModeSupportedFn.");
    exposureMode_ = static_cast<Camera_ExposureMode>(mode);
    ret_ = OH_CaptureSession_IsExposureModeSupported(captureSession_, exposureMode_, &isExposureModeSupported_);

    //     if (&isExposureModeSupported_ == nullptr || ret_ != CAMERA_OK) {
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "IsExposureModeSupportedFn failed.");
        return CAMERA_INVALID_ARGUMENT;
    }

    ret_ = OH_CaptureSession_SetExposureMode(captureSession_, exposureMode_);

    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "IsExposureModeSupportedFn failed.");
        return CAMERA_INVALID_ARGUMENT;
    }

    ret_ = OH_CaptureSession_GetExposureMode(captureSession_, &exposureMode_);

    //     if (&exposureMode_ == nullptr || ret_ != CAMERA_OK) {
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "IsExposureModeSupportedFn failed.");
        return CAMERA_INVALID_ARGUMENT;
    }

    OH_LOG_INFO(LOG_APP, "IsExposureModeSupportedFn end.");
    return ret_;
}

Camera_ErrorCode NDKCamera::IsMeteringPoint(int x, int y) {
    OH_LOG_ERROR(LOG_APP, "enter IsMeteringPoint.");
    ret_ = OH_CaptureSession_GetExposureMode(captureSession_, &exposureMode_);
    //     if (&exposureMode_ == nullptr || ret_ != CAMERA_OK) {
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "IsExposureModeSupportedFn failed.");
        return CAMERA_INVALID_ARGUMENT;
    }
    Camera_Point exposurePoint;
    exposurePoint.x = x;
    exposurePoint.y = y;

    ret_ = OH_CaptureSession_SetMeteringPoint(captureSession_, exposurePoint);
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_SetMeteringPoint failed.");
        return CAMERA_INVALID_ARGUMENT;
    }

    ret_ = OH_CaptureSession_GetMeteringPoint(captureSession_, &exposurePoint);
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_GetMeteringPoint failed.");
        return CAMERA_INVALID_ARGUMENT;
    }
    OH_LOG_INFO(LOG_APP, "IsMeteringPoint end.");
    return ret_;
}

Camera_ErrorCode NDKCamera::IsExposureBiasRange(int exposureBias) {
    OH_LOG_ERROR(LOG_APP, "enter IsExposureBiasRange.");
    float exposureBiasValue = (float)exposureBias;
    ret_ = OH_CaptureSession_GetExposureBiasRange(captureSession_, &minExposureBias_, &maxExposureBias_, &step_);
    //     if (&minExposureBias_ == nullptr || &maxExposureBias_ == nullptr || &step_ == nullptr || ret_ != CAMERA_OK) {
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "IsExposureModeSupportedFn failed.");
        return CAMERA_INVALID_ARGUMENT;
    }

    ret_ = OH_CaptureSession_SetExposureBias(captureSession_, exposureBiasValue);
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_SetExposureBias failed.");
        return CAMERA_INVALID_ARGUMENT;
    }

    ret_ = OH_CaptureSession_GetExposureBias(captureSession_, &exposureBiasValue);
    //     if (&exposureBiasValue == nullptr || ret_ != CAMERA_OK) {
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_GetExposureBias failed.");
        return CAMERA_INVALID_ARGUMENT;
    }
    OH_LOG_INFO(LOG_APP, "IsExposureBiasRange end.");
    return ret_;
}

Camera_ErrorCode NDKCamera::IsFocusModeSupported(uint32_t mode) {
    OH_LOG_ERROR(LOG_APP, "enter IsFocusModeSupported.");
    Camera_FocusMode focusMode = static_cast<Camera_FocusMode>(mode);
    ret_ = OH_CaptureSession_IsFocusModeSupported(captureSession_, focusMode, &isFocusModeSupported_);
    //     if (&isFocusModeSupported_ == nullptr || &maxExposureBias_ == nullptr || &step_ == nullptr || ret_ !=
    //     CAMERA_OK) {
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "IsFocusModeSupported failed.");
        return CAMERA_INVALID_ARGUMENT;
    }

    OH_LOG_INFO(LOG_APP, "IsFocusModeSupported end.");
    return ret_;
}
Camera_ErrorCode NDKCamera::IsFocusMode(uint32_t mode) {
    OH_LOG_ERROR(LOG_APP, "enter IsFocusMode.");
    Camera_FocusMode focusMode = static_cast<Camera_FocusMode>(mode);
    ret_ = OH_CaptureSession_IsFocusModeSupported(captureSession_, focusMode, &isFocusModeSupported_);
    //     if (&isFocusModeSupported_ == nullptr || &maxExposureBias_ == nullptr || &step_ == nullptr || ret_ !=
    //     CAMERA_OK) {
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "IsFocusMode failed.");
        return CAMERA_INVALID_ARGUMENT;
    }

    ret_ = OH_CaptureSession_SetFocusMode(captureSession_, focusMode);
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "IsFocusMode failed.");
        return CAMERA_INVALID_ARGUMENT;
    }

    ret_ = OH_CaptureSession_GetFocusMode(captureSession_, &focusMode);
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "IsFocusMode failed.");
        return CAMERA_INVALID_ARGUMENT;
    }

    OH_LOG_INFO(LOG_APP, "IsFocusMode end.");
    return ret_;
}

Camera_ErrorCode NDKCamera::IsFocusPoint(float x, float y) {
    OH_LOG_ERROR(LOG_APP, "enter IsFocusPoint.");
    Camera_Point focusPoint;
    focusPoint.x = x;
    focusPoint.y = y;
    ret_ = OH_CaptureSession_SetFocusPoint(captureSession_, focusPoint);
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_SetFocusPoint failed.");
        return CAMERA_INVALID_ARGUMENT;
    }

    ret_ = OH_CaptureSession_GetFocusPoint(captureSession_, &focusPoint);
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_GetFocusPoint failed.");
        return CAMERA_INVALID_ARGUMENT;
    }

    OH_LOG_INFO(LOG_APP, "IsFocusPoint end.");
    return ret_;
}

int32_t NDKCamera::GetVideoFrameWidth(void) {
    OH_LOG_ERROR(LOG_APP, "enter IsFocusPoint.");
    videoProfile_ = cameraOutputCapability_->videoProfiles[0];
    if (videoProfile_ == nullptr) {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_GetFocusPoint failed.");
        return CAMERA_INVALID_ARGUMENT;
    }

    OH_LOG_INFO(LOG_APP, "GetVideoFrameWidth end.");
    return videoProfile_->size.width;
}

int32_t NDKCamera::GetVideoFrameHeight(void) {
    OH_LOG_ERROR(LOG_APP, "enter IsFocusPoint.");
    videoProfile_ = cameraOutputCapability_->videoProfiles[0];
    if (videoProfile_ == nullptr) {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_GetFocusPoint failed.");
        return CAMERA_INVALID_ARGUMENT;
    }

    OH_LOG_INFO(LOG_APP, "GetVideoFrameWidth end.");
    return videoProfile_->size.height;
}

int32_t NDKCamera::GetVideoFrameRate(void) {
    OH_LOG_ERROR(LOG_APP, "enter IsFocusPoint.");
    videoProfile_ = cameraOutputCapability_->videoProfiles[0];
    if (videoProfile_ == nullptr) {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_GetFocusPoint failed.");
        return CAMERA_INVALID_ARGUMENT;
    }

    OH_LOG_INFO(LOG_APP, "GetVideoFrameWidth end.");
    return videoProfile_->range.min;
}

Camera_ErrorCode NDKCamera::VideoOutputStop(void) {
    OH_LOG_ERROR(LOG_APP, " VideoOutputStop into");
    ret_ = OH_VideoOutput_Stop(videoOutput_);
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "startPhoto failed.");
        return CAMERA_INVALID_ARGUMENT;
    }
    return ret_;
}

Camera_ErrorCode NDKCamera::VideoOutputRelease(void) {
    OH_LOG_ERROR(LOG_APP, " VideoOutputRelease into");
    if (videoOutput_ == nullptr) {
        return CAMERA_OK;
    }
    ret_ = OH_VideoOutput_Release(videoOutput_);
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "startPhoto failed.");
        return CAMERA_INVALID_ARGUMENT;
    }
    videoOutput_ = nullptr;
    return ret_;
}
Camera_ErrorCode NDKCamera::TakePicture(void) {
    Camera_ErrorCode ret = CAMERA_OK;
    ret = OH_PhotoOutput_Capture(photoOutput_);
    OH_LOG_ERROR(LOG_APP, "takePicture OH_PhotoOutput_Capture ret = %{public}d.", ret);
    if (ret != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "startPhoto failed.");
        return CAMERA_INVALID_ARGUMENT;
    }
    return ret;
}

Camera_ErrorCode NDKCamera::TakePictureWithPhotoSettings(Camera_PhotoCaptureSetting photosetting) {
    Camera_ErrorCode ret = CAMERA_OK;
    ret = OH_PhotoOutput_Capture_WithCaptureSetting(photoOutput_, photosetting);
    OH_LOG_ERROR(LOG_APP, "takePicture OH_PhotoOutput_Capture ret = %{public}d.", ret);
    if (ret != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "startPhoto failed.");
        return CAMERA_INVALID_ARGUMENT;
    }
    return ret;
}

// Camera_ErrorCode NDKCamera::CreatePhotoOutputWithoutSurfaceId() {
//     DRAWING_LOGD("NDKCamera::CreatePhotoOutput into createWithoutSurfaceID branch!");
//     profile_ = cameraOutputCapability_->photoProfiles[0];
//     profile_->size.width = DEFAULT_WIDTH;
//     profile_->size.height = DEFAULT_HEIGHT;
//     profile_->format = CAMERA_FORMAT_JPEG;
//     ret_ = OH_CameraManager_CreatePhotoOutputWithoutSurface(cameraManager_, profile_, &photoOutput_);
//     if (photoOutput_ == nullptr || ret_ != CAMERA_OK) {
//         DRAWING_LOGD("OH_CameraManager_CreatePhotoOutputWithoutSurface failed!");
//         OH_LOG_ERROR(LOG_APP, "CreatePhotoOutput failed.");
//         return CAMERA_INVALID_ARGUMENT;
//     }
//     DRAWING_LOGD("NDKCamera::CreatePhotoOutput register photo asset available callback!");
//     MediaAssetManagerCreate();
//     PhotoOutputRegisterPhotoAssetAvailableCallback();
//     return ret_;
// }
//
// void NDKCamera::MediaAssetManagerCreate(void) {
//     DRAWING_LOGD("NDKCamera::MediaAssetManagerCreate start!");
//     g_mediaAssetManager = OH_MediaAssetManager_Create();
//     if (g_mediaAssetManager == nullptr) {
//         DRAWING_LOGD("NDKCamera::MediaAssetManagerCreate failed.");
//         return;
//     }
//     DRAWING_LOGD("NDKCamera::MediaAssetManagerCreate end!");
//     return;
// }

// void onPhotoAssetAvailable(Camera_PhotoOutput *photoOutput, OH_MediaAsset *mediaAsset) {
//     DRAWING_LOGD("onPhotoAssetAvailable start!");
//     if (photoOutput == nullptr) {
//         DRAWING_LOGD("onPhotoAssetAvailable return because photoOutput is nullptr !");
//         return;
//     }
//     if (mediaAsset == nullptr) {
//         DRAWING_LOGD("onPhotoAssetAvailable return because mediaAsset is nullptr !");
//         return;
//     }
//     if (g_mediaAsset != nullptr) {
//         NDKCamera::MediaAssetRelease();
//     }
//     g_mediaAsset = mediaAsset;
//
//     if (g_changeRequest) {
//         NDKCamera::ChangeRequestRelease();
//     }
//     NDKCamera::MediaAssetChangeRequestCreate();
//
//     NDKCamera::MediaAssetManagerRequestImage();
//
//     DRAWING_LOGD("onPhotoAssetAvailable finish!");
//     return;
// }

// Camera_ErrorCode NDKCamera::PhotoOutputRegisterPhotoAssetAvailableCallback(void) {
//     DRAWING_LOGD("NDKCamera::PhotoOutputRegisterPhotoAssetAvailableCallback start!");
//     ret_ = OH_PhotoOutput_RegisterPhotoAssetAvailableCallback(photoOutput_, onPhotoAssetAvailable);
//     if (ret_ != CAMERA_OK) {
//         DRAWING_LOGD("NDKCamera::PhotoOutputRegisterPhotoAssetAvailableCallback failed.");
//         return CAMERA_INVALID_ARGUMENT;
//     }
//     DRAWING_LOGD("NDKCamera::PhotoOutputRegisterPhotoAssetAvailableCallback return with ret code: %{public}d", ret_);
//     return ret_;
// }

/*
void onImageDataPrepared(MediaLibrary_ErrorCode result, MediaLibrary_RequestId requestId,
                         MediaLibrary_MediaQuality mediaQuality, MediaLibrary_MediaContentType type,
                         OH_ImageSourceNative *imageSourceNative) {
    DRAWING_LOGD("onImageDataPrepared start!");
    if (imageSourceNative == nullptr) {
        DRAWING_LOGD("onImageDataPrepared imageSourceNative is nullptr!");
        return;
    }
    g_imageSourceNative = imageSourceNative;
    auto qCb = g_requestImageQualityCallback;
    if (mediaQuality == MediaLibrary_MediaQuality::MEDIA_LIBRARY_QUALITY_FAST) {
        DRAWING_LOGD("onImageDataPrepared mediaQuality is MEDIA_LIBRARY_QUALITY_FAST!");
        g_mediaQualityCb = "fast";
        qCb(g_mediaQualityCb);
    }
    if (mediaQuality == MediaLibrary_MediaQuality::MEDIA_LIBRARY_QUALITY_FULL) {
        DRAWING_LOGD("onImageDataPrepared mediaQuality is MEDIA_LIBRARY_QUALITY_FULL!");
        g_mediaQualityCb = "high";
        qCb(g_mediaQualityCb);
    }
    OH_DecodingOptions *decodingOptions = nullptr;
    OH_PixelmapNative *pixelMapNative = nullptr;
    Image_ErrorCode ret = IMAGE_SUCCESS;
    ret = OH_ImageSourceNative_CreatePixelmap(imageSourceNative, decodingOptions, &pixelMapNative);
    if (ret != IMAGE_SUCCESS) {
        DRAWING_LOGD(" OH_ImageSourceNative_CreatePixelmap failed.");
        return;
    }
    if (pixelMapNative == nullptr) {
        DRAWING_LOGD(" get pixel native faild");
    }
    g_pixelmapNative = pixelMapNative;
    NDKCamera::RequestImageBufferCallback(pixelMapNative);
    return;
}

void NDKCamera::MediaAssetManagerRequestImage(void) {
    DRAWING_LOGD("NDKCamera::MediaAssetManagerRequestImage start!");
    g_requestOptions.deliveryMode = g_deliveryMode;
    DRAWING_LOGD("NDKCamera::MediaAssetManagerRequestImage deliveryMode: %{public}d", g_requestOptions.deliveryMode);
    result = OH_MediaAssetManager_RequestImage(g_mediaAssetManager, g_mediaAsset, g_requestOptions, &g_requestId,
                                               onImageDataPrepared);
    if (result != MEDIA_LIBRARY_OK) {
        DRAWING_LOGD("NDKCamera::MediaAssetManagerRequestImage failed.");
        return;
    }
    DRAWING_LOGD("NDKCamera::MediaAssetManagerRequestImage end!");
    return;
}
*/
/*

void NDKCamera::EditRotateImage() {
    if (g_pixelmapNative == nullptr) {
        DRAWING_LOGE("EditCurImage error pixel mapNative is null");
        return;
    }
    OH_ImagePackerNative *imagePacker;
    OH_ImagePackerNative_Create(&imagePacker);
    OH_PackingOptions *options;
    OH_PackingOptions_Create(&options);
    char format[] = "image/jpeg";
    Image_MimeType image_MimeType = {format, strlen(format)};
    OH_PackingOptions_SetMimeType(options, &image_MimeType);
    OH_PackingOptions_SetQuality(options, DEFAULT_QUALITY);
    size_t outsize = 25 * 1024 * 1024;

    Image_ErrorCode ret = IMAGE_SUCCESS;
    DRAWING_LOGD("EditCurImage OH_PixelmapNative_Rotate angle  %{public}f.", g_angle);
    ret = OH_PixelmapNative_Rotate(g_pixelmapNative, g_angle);
    if (ret != IMAGE_SUCCESS) {
        OH_LOG_ERROR(LOG_APP, "EditCurImage OH_PixelmapNative_Rotate failed, errCode: %{public}d.", ret);
        return;
    }
    auto outData = std::make_unique<uint8_t[]>(outsize);
    Image_ErrorCode code =
        OH_ImagePackerNative_PackToDataFromPixelmap(imagePacker, options, g_pixelmapNative, outData.get(), &outsize);
    DRAWING_LOGD("OH_ImagePackerNative_PackToDataFromPixelmap ret code:%{public}d outsize:%{public}zu", code, outsize);

    EditImage(outData.get(), outsize, g_pixelmapNative);
}

void NDKCamera::EditImage(uint8_t *buffer, size_t size, OH_PixelmapNative *pixelMap) {
    if (g_changeRequest == nullptr) {
        DRAWING_LOGE("NDKCamera::EditImage get current g_changeRequest failed!");
    }
    MediaLibrary_ErrorCode errCode =
        OH_MediaAssetChangeRequest_AddResourceWithBuffer(g_changeRequest, MEDIA_LIBRARY_IMAGE_RESOURCE, buffer, size);
    DRAWING_LOGD("NDKCamera::EditImage AddResourceWithBuffer get errCode:%{public}d", errCode);

    errCode = OH_MediaAccessHelper_ApplyChanges(g_changeRequest);
    DRAWING_LOGD("NDKCamera::EditImage ApplyChanges get errCode:%{public}d", errCode);
    RequestImageBufferCallback(pixelMap);
}
*/
/*
void NDKCamera::RequestImageBufferCallback(OH_PixelmapNative *pixelMap) {
    OH_Pixelmap_ImageInfo *imageInfo;
    OH_PixelmapImageInfo_Create(&imageInfo);
    Image_ErrorCode infoRet = OH_PixelmapNative_GetImageInfo(pixelMap, imageInfo);
    DRAWING_LOGD("NDKCamera::EditImage OH_PixelmapNative_GetImageInfo ret:%{public}d", infoRet);
    uint32_t width;
    uint32_t height;
    uint32_t rowStride;
    OH_PixelmapImageInfo_GetWidth(imageInfo, &width);
    OH_PixelmapImageInfo_GetHeight(imageInfo, &height);
    OH_PixelmapImageInfo_GetRowStride(imageInfo, &rowStride);
    DRAWING_LOGD(" NDKCamera::EditImage PixelmapImageInfo:%{public}d height:%{public}d rowStride:%{public}d", width,
                 height, rowStride);
    size_t size_ = rowStride * height;
    auto pixelBuffer = std::make_unique<uint8_t[]>(size_);
    Image_ErrorCode ret = OH_PixelmapNative_ReadPixels(pixelMap, pixelBuffer.get(), &size_);
    if (ret != IMAGE_SUCCESS) {
        DRAWING_LOGD(" NDKCamera::EditImage OH_PixelmapNative_ReadPixels failed. ret: %{public}d", ret);
        return;
    }
    auto cb = (void (*)(uint8_t *, size_t))(g_requestImageBufferCallback);
    cb(pixelBuffer.get(), size_);
}

void NDKCamera::MediaAssetRelease(void) {
    DRAWING_LOGD("NDKCamera::MediaAssetRelease start!");
    result = OH_MediaAsset_Release(g_mediaAsset);
    if (result != MEDIA_LIBRARY_OK) {
        DRAWING_LOGD("NDKCamera::MediaAssetRelease failed.");
        return;
    }
    g_mediaAsset = nullptr;
    DRAWING_LOGD("NDKCamera::MediaAssetRelease end!");
    return;
}

void NDKCamera::ChangeRequestRelease(void) {
    DRAWING_LOGD("NDKCamera::ChangeRequestRelease start!");
    result = OH_MediaAssetChangeRequest_Release(g_changeRequest);
    if (result != MEDIA_LIBRARY_OK) {
        DRAWING_LOGD("NDKCamera::ChangeRequestRelease failed.");
        return;
    }
    g_changeRequest = nullptr;
    DRAWING_LOGD("NDKCamera::ChangeRequestRelease end!");
    return;
}*/
/*
void NDKCamera::MediaAssetManagerRelease(void)
{
    DRAWING_LOGD("NDKCamera::MediaAssetManagerRelease start!");
    result = OH_MediaAssetManager_Release(g_mediaAssetManager);
    if (result != MEDIA_LIBRARY_OK) {
        DRAWING_LOGD("NDKCamera::MediaAssetManagerRelease failed.");
        return;
    }
    g_mediaAssetManager = nullptr;
    DRAWING_LOGD("NDKCamera::MediaAssetManagerRelease end!");
    return;
}*/

/*
void NDKCamera::MediaAssetChangeRequestCreate(void) {
    DRAWING_LOGD("NDKCamera::MediaAssetChangeRequestCreate start!");
    g_changeRequest = OH_MediaAssetChangeRequest_Create(g_mediaAsset);
    if (g_changeRequest == nullptr) {
        DRAWING_LOGD("NDKCamera::MediaAssetChangeRequestCreate failed.");
        return;
    }
    DRAWING_LOGD("NDKCamera::MediaAssetChangeRequestCreate end!");
    return;
}

void NDKCamera::ChangeRequestSaveCameraPhoto(void) {
    DRAWING_LOGD("NDKCamera::ChangeRequestSaveCameraPhoto start!");
    result = OH_MediaAssetChangeRequest_SaveCameraPhoto(g_changeRequest, IMAGE_TYPE_JPEG);
    if (result != MEDIA_LIBRARY_OK) {
        DRAWING_LOGD("NDKCamera::ChangeRequestSaveCameraPhoto failed.");
        return;
    }
    result = OH_MediaAccessHelper_ApplyChanges(g_changeRequest);
    if (result != MEDIA_LIBRARY_OK) {
        DRAWING_LOGD("NDKCamera::ChangeRequestSaveCameraPhoto OH_MediaAccessHelper_ApplyChanges failed.");
        return;
    }
    DRAWING_LOGD("NDKCamera::ChangeRequestSaveCameraPhoto end!");
    return;
}
*/

/*
void NDKCamera::ChangeRequestDiscardCameraPhoto(void) {
    DRAWING_LOGD("NDKCamera::ChangeRequestDiscardCameraPhoto start!");
    result = OH_MediaAssetChangeRequest_DiscardCameraPhoto(g_changeRequest);
    if (result != MEDIA_LIBRARY_OK) {
        DRAWING_LOGD("NDKCamera::ChangeRequestDiscardCameraPhoto failed.");
        return;
    }
    result = OH_MediaAccessHelper_ApplyChanges(g_changeRequest);
    if (result != MEDIA_LIBRARY_OK) {
        DRAWING_LOGD("NDKCamera::ChangeRequestDiscardCameraPhoto OH_MediaAccessHelper_ApplyChanges failed.");
        return;
    }
    DRAWING_LOGD("NDKCamera::ChangeRequestDiscardCameraPhoto end!");
    return;
}

Camera_ErrorCode NDKCamera::SetRequestOption(uint32_t requestOption) {
    if (requestOption == 0) {
        g_deliveryMode = MEDIA_LIBRARY_FAST_MODE;
    } else if (requestOption == 1) {
        g_deliveryMode = MEDIA_LIBRARY_HIGH_QUALITY_MODE;
    } else if (requestOption == REQUEST_OPTION_TWO) {
        g_deliveryMode = MEDIA_LIBRARY_BALANCED_MODE;
    } else {
        return CAMERA_INVALID_ARGUMENT;
    }
    return CAMERA_OK;
}
*/

/*
Camera_ErrorCode NDKCamera::RequestImageQualityCallback(void (*cb)(char *)) {
    if (cb == nullptr) {
        OH_LOG_ERROR(LOG_APP, " RequestImageCallback invalid error");
        return CAMERA_INVALID_ARGUMENT;
    }
    g_requestImageQualityCallback = cb;

    return CAMERA_OK;
}

Camera_ErrorCode NDKCamera::RequestImageBufferCallback(void (*cb)(uint8_t *, size_t)) {
    if (cb == nullptr) {
        OH_LOG_ERROR(LOG_APP, " RequestImageBufferCallback invalid error");
        return CAMERA_INVALID_ARGUMENT;
    }
    g_requestImageBufferCallback = cb;

    return CAMERA_OK;
}
*/

// CameraManager Callback
void CameraManagerStatusCallback(Camera_Manager *cameraManager, Camera_StatusInfo *status) {
    OH_LOG_INFO(LOG_APP, "CameraManagerStatusCallback");
}

CameraManager_Callbacks *NDKCamera::GetCameraManagerListener(void) {
    static CameraManager_Callbacks cameraManagerListener = {.onCameraStatus = CameraManagerStatusCallback};
    return &cameraManagerListener;
}

Camera_ErrorCode NDKCamera::CameraManagerRegisterCallback(void) {
    ret_ = OH_CameraManager_RegisterCallback(cameraManager_, GetCameraManagerListener());
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "OH_CameraManager_RegisterCallback failed.");
    }
    return ret_;
}

// CameraInput Callback
void OnCameraInputError(const Camera_Input *cameraInput, Camera_ErrorCode errorCode) {
    OH_LOG_INFO(LOG_APP, "OnCameraInput errorCode = %{public}d", errorCode);
}

CameraInput_Callbacks *NDKCamera::GetCameraInputListener(void) {
    static CameraInput_Callbacks cameraInputCallbacks = {.onError = OnCameraInputError};
    return &cameraInputCallbacks;
}

Camera_ErrorCode NDKCamera::CameraInputRegisterCallback(void) {
    ret_ = OH_CameraInput_RegisterCallback(cameraInput_, GetCameraInputListener());
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "OH_CameraInput_RegisterCallback failed.");
    }
    return ret_;
}

// PreviewOutput Callback
void PreviewOutputOnFrameStart(Camera_PreviewOutput *previewOutput) {
    OH_LOG_INFO(LOG_APP, "PreviewOutputOnFrameStart");
}

void PreviewOutputOnFrameEnd(Camera_PreviewOutput *previewOutput, int32_t frameCount) {
    OH_LOG_INFO(LOG_APP, "PreviewOutput frameCount = %{public}d", frameCount);
}

void PreviewOutputOnError(Camera_PreviewOutput *previewOutput, Camera_ErrorCode errorCode) {
    OH_LOG_INFO(LOG_APP, "PreviewOutput errorCode = %{public}d", errorCode);
}

PreviewOutput_Callbacks *NDKCamera::GetPreviewOutputListener(void) {
    static PreviewOutput_Callbacks previewOutputListener = {.onFrameStart = PreviewOutputOnFrameStart,
                                                            .onFrameEnd = PreviewOutputOnFrameEnd,
                                                            .onError = PreviewOutputOnError};
    return &previewOutputListener;
}

Camera_ErrorCode NDKCamera::PreviewOutputRegisterCallback(void) {
    ret_ = OH_PreviewOutput_RegisterCallback(previewOutput_, GetPreviewOutputListener());
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "OH_PreviewOutput_RegisterCallback failed.");
    }
    return ret_;
}

// PhotoOutput Callback
void PhotoOutputOnFrameStart(Camera_PhotoOutput *photoOutput) {
    DRAWING_LOGD("PhotoOutputOnFrameStart start!");
    OH_LOG_INFO(LOG_APP, "PhotoOutputOnFrameStart");
}

void PhotoOutputOnFrameShutter(Camera_PhotoOutput *photoOutput, Camera_FrameShutterInfo *info) {
    DRAWING_LOGD("PhotoOutputOnFrameShutter start!");
    OH_LOG_INFO(LOG_APP, "PhotoOutputOnFrameShutter");
}

void PhotoOutputOnFrameEnd(Camera_PhotoOutput *photoOutput, int32_t frameCount) {
    DRAWING_LOGD("PhotoOutputOnFrameEnd start!");
    OH_LOG_INFO(LOG_APP, "PhotoOutput frameCount = %{public}d", frameCount);
}

void PhotoOutputOnError(Camera_PhotoOutput *photoOutput, Camera_ErrorCode errorCode) {
    DRAWING_LOGD("PhotoOutputOnError start!");
    OH_LOG_INFO(LOG_APP, "PhotoOutput errorCode = %{public}d", errorCode);
}

PhotoOutput_Callbacks *NDKCamera::GetPhotoOutputListener(void) {
    static PhotoOutput_Callbacks photoOutputListener = {.onFrameStart = PhotoOutputOnFrameStart,
                                                        .onFrameShutter = PhotoOutputOnFrameShutter,
                                                        .onFrameEnd = PhotoOutputOnFrameEnd,
                                                        .onError = PhotoOutputOnError};
    return &photoOutputListener;
}

// PhotoOutput Callback
void VideoOutputOnFrameStart(Camera_VideoOutput *videoOutput) {
    DRAWING_LOGD("VideoOutputOnFrameStart start!");
    OH_LOG_INFO(LOG_APP, "VideoOutputOnFrameStart");
}
void VideoOutputOnFrameEnd(Camera_VideoOutput *videoOutput, int32_t frameCount) {
    DRAWING_LOGD("VideoOutputOnFrameEnd start!");
    OH_LOG_INFO(LOG_APP, "VideoOutputOnFrameEnd frameCount = %{public}d", frameCount);
}
void VideoOutputOnError(Camera_VideoOutput *videoOutput, Camera_ErrorCode errorCode) {
    DRAWING_LOGD("VideoOutputOnError start!");
    OH_LOG_INFO(LOG_APP, "VideoOutputOnError errorCode = %{public}d", errorCode);
}


VideoOutput_Callbacks *NDKCamera::GetVideoOutputListener(void) {
    static VideoOutput_Callbacks videoOutputListener = {
        .onFrameStart = VideoOutputOnFrameStart, .onFrameEnd = VideoOutputOnFrameEnd, .onError = VideoOutputOnError};
    return &videoOutputListener;
}

Camera_ErrorCode NDKCamera::PhotoOutputRegisterCallback(void) {
    ret_ = OH_PhotoOutput_RegisterCallback(photoOutput_, GetPhotoOutputListener());
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "OH_PhotoOutput_RegisterCallback failed.");
    }
    return ret_;
}


void OnMetadataObjectAvailable(Camera_MetadataOutput *metadataOutput, Camera_MetadataObject *metadataObject,
                               uint32_t size) {
    DRAWING_LOGD("OnMetadataObjectAvailable start!");
    OH_LOG_INFO(LOG_APP, "OnMetadataObjectAvailable size = %{public}d", size);
}

void OnMetadataOutputError(Camera_MetadataOutput *metadataOutput, Camera_ErrorCode errorCode) {
    DRAWING_LOGD("OnMetadataOutputError start!");
    OH_LOG_INFO(LOG_APP, "OnMetadataOutputError errorCode = %{public}d", errorCode);
}
MetadataOutput_Callbacks *NDKCamera::GetMetadataOutputListener(void) {
    static MetadataOutput_Callbacks metadataOutputListener = {.onMetadataObjectAvailable = OnMetadataObjectAvailable,
                                                              .onError = OnMetadataOutputError};
    return &metadataOutputListener;
}

Camera_ErrorCode NDKCamera::MetadataOutputRegisterCallback(void) {
    ret_ = OH_MetadataOutput_RegisterCallback(metadataOutput_, GetMetadataOutputListener());
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "OH_PhotoOutput_RegisterCallback failed.");
    }
    return ret_;
}

Camera_ErrorCode NDKCamera::VideoOutputRegisterCallback(void) {
    ret_ = OH_VideoOutput_RegisterCallback(videoOutput_, GetVideoOutputListener());
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "OH_PhotoOutput_RegisterCallback failed.");
    }
    return ret_;
}

// Session Callback
void CaptureSessionOnFocusStateChange(Camera_CaptureSession *session, Camera_FocusState focusState) {
    OH_LOG_INFO(LOG_APP, "CaptureSession_Callbacks CaptureSessionOnFocusStateChange");
    OH_LOG_INFO(LOG_APP, "CaptureSessionOnFocusStateChange");
}

void CaptureSessionOnError(Camera_CaptureSession *session, Camera_ErrorCode errorCode) {
    OH_LOG_INFO(LOG_APP, "CaptureSession_Callbacks CaptureSessionOnError");
    OH_LOG_INFO(LOG_APP, "CaptureSession errorCode = %{public}d", errorCode);
}

CaptureSession_Callbacks *NDKCamera::GetCaptureSessionRegister(void) {
    static CaptureSession_Callbacks captureSessionCallbacks = {.onFocusStateChange = CaptureSessionOnFocusStateChange,
                                                               .onError = CaptureSessionOnError};
    return &captureSessionCallbacks;
}

Camera_ErrorCode NDKCamera::CaptureSessionRegisterCallback(void) {
    ret_ = OH_CaptureSession_RegisterCallback(captureSession_, GetCaptureSessionRegister());
    if (ret_ != CAMERA_OK) {
        OH_LOG_ERROR(LOG_APP, "OH_CaptureSession_RegisterCallback failed.");
    }
    return ret_;
}
} // namespace OHOS_CAMERA_SAMPLE